/**
 * @filename:InStockServiceImpl Dec 21, 2023
 * @project Wonder Vue Admin Api  1.1.0
 * Copyright(c) 2022 Wonder Co. Ltd. 
 * All right reserved. 
 */
package com.wonder.app.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.system.UserInfo;
import com.vtuzx.core.bean.dto.VtuzxMap;
import com.vtuzx.core.utils.VtuzxUtil;
import com.wonder.app.domain.*;
import com.wonder.app.mapper.InStockDao;
import com.wonder.app.mapper.InStockDetailDao;
import com.wonder.app.mapper.MaterialDao;
import com.wonder.app.service.InStockDetailService;
import com.wonder.app.service.InStockService;
import com.wonder.app.request.InStockRequest;
import com.wonder.app.service.InventoryService;
import com.wonder.app.service.KingdeeOrderService;
import com.wonder.bean.kingdee.xqc.BillMaterial;
import com.wonder.common.utils.DateUtils;
import com.wonder.common.utils.MapUtils;
import com.wonder.common.utils.StringUtils;
import com.wonder.common.utils.MessageUtils;
import com.wonder.common.common.AjaxResult;

import java.util.*;
import java.util.stream.Collectors;

import com.wonder.constant.BillEvent;
import com.wonder.constant.BillType;
import com.wonder.constant.IXqcConst;
import jnr.ffi.annotations.In;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

/**   
 * @Description:TODO(生产入库服务实现)
 *
 * @version: 1.1.0
 * @author: Wonder
 * 
 */
@Service
public class InStockServiceImpl  extends ServiceImpl<InStockDao, InStock> implements InStockService  {
	/**
	 * Logger
	 */
	private static final Logger _logger = LoggerFactory.getLogger(InStockServiceImpl.class);

	@Autowired
	private InStockDetailDao inStockDetailDao;

	@Autowired
	private InStockDao inStockDao;

	@Autowired
	private InStockService inStockService;

	@Autowired
	private InStockDetailService inStockDetailService;

	@Autowired
	private MaterialDao materialDao;

	@Autowired
	private KingdeeOrderService kingdeeOrderService;

	@Autowired
	private InventoryService inventoryService;

    /**
     * 验证生产入库信息
     * 
     * @param inStock
     * @param type
     * @return String
     */
    @Override
    public String validate(InStock inStock,String type){
    
    
       return "";
    }
    
    
    /**
	 * Description:生产入库分页返回
	 * @param request //检索条件
	 * @param page //分页参数
	 * @return IPage<InStock>   //分页记录
	 */
	@Override 
	public IPage<InStock> selectList(InStockRequest request, Page<InStock> page){
	    LambdaQueryWrapper<InStock> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		lambdaQueryWrapper.eq(InStock::getQuality,true);
	    if(null != request.getStockNo()){
			lambdaQueryWrapper.eq(InStock::getStockNo, request.getStockNo());
		}
		if (null != request.getBillNo()){
			lambdaQueryWrapper.like(InStock::getBillNo, request.getBillNo());
		}

	    if (null != request.getId()) {
	       lambdaQueryWrapper.eq(InStock::getId, request.getId());
	      }               

             
        if (request.getCreateTime() != null){
        	Date[] createTime=request.getCreateTime();
        	if(createTime.length>0)
        	  lambdaQueryWrapper.ge(InStock::getCreateTime, createTime[0]); 
        	if(createTime.length==2)
        	  lambdaQueryWrapper.le(InStock::getCreateTime,DateUtils.dateToStr(createTime[1],"yyyy-MM-dd")+ " 23:59:59");
        	
        }    
             
        if (StringUtils.hasText(request.getTaskBillNo())) {
			    lambdaQueryWrapper.like(InStock::getTaskBillNo, request.getTaskBillNo()); 
		    } 
             
        if (StringUtils.hasText(request.getCreateUserName())) {
			    lambdaQueryWrapper.like(InStock::getCreateUserName, request.getCreateUserName()); 
		    } 
             
        
		lambdaQueryWrapper.orderByDesc(InStock::getId);	
		Page<InStock> selectPage = this.baseMapper.selectPage(page, lambdaQueryWrapper);
		return selectPage;
    }

	@Override
	public VtuzxMap getInStockDetail(String billNo) {
		VtuzxMap data = new VtuzxMap();
		InStock inStock = inStockDao.selectOne(new QueryWrapper<InStock>()
				.eq("billNo",billNo));
		List<InStockDetail> detailList = inStockDetailDao.selectList(new QueryWrapper<InStockDetail>()
				.eq("billNo", billNo));
		data.append("header",inStock)
				.append("dataList",detailList);

		return data;
	}

	@Override
	public boolean unAuditInStock(Long user_id, String userName, Long id) {
		InStock inStock = inStockDao.selectById(id);
		inStock.setUpdateTime(new DateTime());
		inStock.setUpdateUserName(userName);
		inStock.setStatus("unAudit");
		String billNo = inStock.getBillNo();

		//反审需要把入库的库存扣减掉
		List<InStockDetail> detailList = inStockDetailDao.selectList(new QueryWrapper<InStockDetail>()
				.eq("entryId", id));

		List<BillMaterial> dataList = new ArrayList<>();//需要增加的库存
		for (InStockDetail data : detailList) {
			BillMaterial material = new BillMaterial();
			material.setMaterialNo(data.getMaterialNo());
			material.setMaterialName(data.getMaterialName());
			material.setMaterialModel(data.getSpecification());
			material.setCount(data.getCount());
			material.setStockNo(data.getStockNo());
			material.setBatchNo(data.getFlot());
			material.setUnit(data.getUnit());
			material.setProduceDate(data.getProduceDate());
			material.setExpiryDate(data.getExpiryDate());
			material.setProduce(data.getIsProduce());
			material.setFlot(data.getIsFlot());
			dataList.add(material);
		}
		try {
			Map<String, Object> stringObjectMap = inventoryService.reduceInventory(user_id, userName, BillEvent.Unaudit, BillType.SCRK, billNo, dataList);
			if (!(Boolean) stringObjectMap.get("status")){
				return false;
			}
		} catch (Exception e){
			_logger.info(e.getMessage());
		}

		boolean isSuccess = inStockService.updateById(inStock);

		return isSuccess;
	}

	@Override
	public boolean auditInStock(Long user_id, String userName, Long id) {
		InStock inStock = inStockDao.selectById(id);
		inStock.setUpdateTime(new DateTime());
		inStock.setUpdateUserName(userName);
		inStock.setStatus("audit");
		inStock.setAuditTime(new DateTime());
		inStock.setAuditUserName(userName);
		String billNo = inStock.getBillNo();
		//审核订单需要扣减库存
		List<InStockDetail> detailList = inStockDetailDao.selectList(new QueryWrapper<InStockDetail>()
				.eq("entryId", id));

		List<BillMaterial> dataList = new ArrayList<>();//需要扣减的库存
		for (InStockDetail data : detailList) {
			BillMaterial material = new BillMaterial();
			material.setMaterialNo(data.getMaterialNo());
			material.setMaterialName(data.getMaterialName());
			material.setMaterialModel(data.getSpecification());
			material.setCount(data.getCount());
			material.setStockNo(data.getStockNo());
			material.setBatchNo(data.getFlot());
			material.setUnit(data.getUnit());
			material.setProduceDate(data.getProduceDate());
			material.setExpiryDate(data.getExpiryDate());
			material.setProduce(data.getIsProduce());
			material.setFlot(data.getIsFlot());
			dataList.add(material);
		}
		boolean isSuccess = inStockService.updateById(inStock);
		//扣减库存
		try {
			Map<String, Object> stringObjectMap = inventoryService.addInventory(user_id, userName, BillEvent.Audit, BillType.SCRK, billNo, dataList);
			if (!(Boolean) stringObjectMap.get("status")){
				return false;
			}

		} catch (Exception e){
			_logger.info(e.getMessage());
		}

//		try {
//			//传金蝶其他入库单
//			Map<String, Object> map = MapUtils.objectToMap(inStock);
//
//			List<Map<String, Object>> objectList = detailList
//					.stream().map(obj -> BeanUtil.beanToMap(obj)).collect(Collectors.toList());
//			kingdeeOrderService.syncOtherIn(user_id,userName,map,objectList);
//		} catch (Exception e){
//			_logger.info(e.getMessage());
//		}
		return isSuccess;
	}

	@Override
	public boolean saveInStock(String userName, Map<String, Object> header, List<Map<String, Object>> dataList) {
		List<InStockDetail> detailList = new ArrayList<>();
		double sumCount = 0;
		for (Map<String,Object> map : dataList) {
			InStockDetail detail = new InStockDetail();
			detail.setId(VtuzxUtil.getLong(map,"id"));
			detail.setBillNo(VtuzxUtil.getString(map,"billNo"));
			detail.setMaterialNo(VtuzxUtil.getString(map,"materialNo"));
			detail.setMaterialName(VtuzxUtil.getString(map,"materialName"));
			detail.setSpecification(VtuzxUtil.getString(map,"specification"));
			detail.setFlot(VtuzxUtil.getString(map,"flot"));
			detail.setProduceDate(VtuzxUtil.parseDate(VtuzxUtil.getString(map,"produceDate")));
			detail.setExpiryDate(VtuzxUtil.parseDate(VtuzxUtil.getString(map,"expiryDate")));
			detail.setUnit(VtuzxUtil.getString(map,"unit"));
			detail.setStockNo(VtuzxUtil.getString(map,"stockNo"));
			detail.setTaskBillNo(VtuzxUtil.getString(map,"taskBillNo"));
			detail.setCount(VtuzxUtil.getDouble(map,"count"));
			detail.setIsProduce(VtuzxUtil.getBoolean(map,"isProduce"));
			detail.setIsFlot(VtuzxUtil.getBoolean(map,"isFlot"));
			detail.setUpdateUserName(userName);
			detail.setUpdateTime(new DateTime());
			detailList.add(detail);
			sumCount += VtuzxUtil.getDouble(map,"count");
		}
		//修改外层的数量
		Long id = Long.parseLong(header.get("id").toString());
		InStock inStock = inStockDao.selectById(id);
		inStock.setCount(sumCount);
		inStock.setStatus("save");
		boolean pickRes = inStockService.updateById(inStock);
		boolean res = inStockDetailService.saveOrUpdateBatch(detailList);
		return res && pickRes;
	}

	@Override
	public Boolean saveInStockPad(JSONObject map) {
		String taskBillNo = map.getStr("taskBillNo");
		String userName = map.getStr("userName");
		String stockNo = map.getStr("stockNo");
		Long userId = map.getLong("userId");
		JSONObject jsonObject = map.getJSONObject("material");//物料信息


		String billNo = IXqcConst.createBillNo(BillType.SCRK);


		String materialNo = jsonObject.getStr("materialNo");
		String materialName = jsonObject.getStr("materialName");
		String specification = jsonObject.getStr("specification");
//			String stockNo = jsonObject.getStr("stockNo");
		String batchNo = jsonObject.getStr("batchNo");
		String unit = jsonObject.getStr("unit");
		double count = jsonObject.getDouble("count");
		String produceDate = jsonObject.getStr("produceDate");
		String workShop = jsonObject.getStr("workShop");//生产车间
		Boolean isDeputy = jsonObject.getBool("isDeputy");//是否关联副产品

		InStockDetail detail = new InStockDetail();
		//查询物料表判断是否启用保质期和批次号
		Material material = materialDao.selectOne(new QueryWrapper<Material>().eq("FNUMBER", materialNo));
		Boolean isProduce = material.getFIsProduce();//是否启用保质期
		Boolean fIsFlot = material.getFIsFlot();//是否启用批次号
		//判断有没有启用批次和保质期
		if (fIsFlot){
			detail.setIsFlot(true);
			detail.setFlot(batchNo);
		} else {
			detail.setIsFlot(false);
		}
		if (isProduce){
			detail.setIsProduce(true);
			Date produce = DateUtils.strToDate(produceDate, "yyyy-MM-dd");//生产日期
			detail.setProduceDate(produce);
			//查询物料表获取保质期
			Integer expperiod = material.getExpperiod();
			String expUnit = material.getExpUnit();
			Date date = null;
			//根据保质期单位判断添加(年,月,日)
			if(expUnit.equals("Y")){
				date = DateUtils.addYears(produce,expperiod);
			} else if (expUnit.equals("M")){
				date = DateUtils.addMonths(produce,expperiod);
			} else if (expUnit.equals("D")){
				date = DateUtils.addDays(produce,expperiod);
			}
			detail.setExpiryDate(date);
		} else {
			detail.setIsProduce(false);
		}
		detail.setBillNo(billNo);
		detail.setMaterialNo(materialNo);
		detail.setMaterialName(materialName);
		detail.setSpecification(specification);
		detail.setUnit(unit);
		detail.setStockNo(stockNo);
		detail.setCreateUserName(userName);
		detail.setCreateUserId(userId);
		detail.setCount(count);
		detail.setUpdateUserName(userName);
		detail.setTaskBillNo(taskBillNo);
		detail.setIsDeputy(isDeputy);
		detail.setWorkShop(workShop);



		//外层表数据
		InStock inStock = new InStock();
		inStock.setStatus("unAudit");
		inStock.setBillNo(billNo);
		inStock.setCount(count);
		inStock.setCreateUserId(userId);
		inStock.setCreateUserName(userName);
		inStock.setTaskBillNo(taskBillNo);
		inStock.setQuality(false);
		inStock.setUpdateUserName(userName);

		inStock.setStockNo(stockNo);
		boolean save = inStockService.save(inStock);
		Long id = inStock.getId();
		detail.setEntryId(id);
		boolean detailRes = inStockDetailService.saveOrUpdate(detail);
		return save && detailRes;
	}

	@Override
	public Boolean quality(String billNo,String userName,Long userId) {

		InStock inStock = inStockDao.selectOne(new LambdaQueryWrapper<InStock>().eq(InStock::getBillNo, billNo));
		inStock.setQuality(true);
		inStockDao.updateById(inStock);
		Long id = inStock.getId();
		//质检后直接审核生产入库单
		boolean res = auditInStock(userId, userName, id);
		return res;
	}

	@Override
	public IPage<InStock> selectQualityList(InStockRequest request, Page<InStock> page) {
		LambdaQueryWrapper<InStock> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		lambdaQueryWrapper.eq(InStock::getQuality,false);
		if(null != request.getStockNo()){
			lambdaQueryWrapper.eq(InStock::getStockNo, request.getStockNo());
		}
		if (null != request.getBillNo()){
			lambdaQueryWrapper.like(InStock::getBillNo, request.getBillNo());
		}

		if (null != request.getId()) {
			lambdaQueryWrapper.eq(InStock::getId, request.getId());
		}


		if (request.getCreateTime() != null){
			Date[] createTime=request.getCreateTime();
			if(createTime.length>0)
				lambdaQueryWrapper.ge(InStock::getCreateTime, createTime[0]);
			if(createTime.length==2)
				lambdaQueryWrapper.le(InStock::getCreateTime,DateUtils.dateToStr(createTime[1],"yyyy-MM-dd")+ " 23:59:59");

		}

		if (StringUtils.hasText(request.getTaskBillNo())) {
			lambdaQueryWrapper.like(InStock::getTaskBillNo, request.getTaskBillNo());
		}

		if (StringUtils.hasText(request.getCreateUserName())) {
			lambdaQueryWrapper.like(InStock::getCreateUserName, request.getCreateUserName());
		}


		lambdaQueryWrapper.orderByDesc(InStock::getId);
		Page<InStock> selectPage = this.baseMapper.selectPage(page, lambdaQueryWrapper);
		return selectPage;
	}


}